package com.winexpress.account;

import com.winexpress.support.NotificationManagementWS_Service;
import com.winexpress.util.SessionAttributes;
import com.winexpress.util.StringValidator;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.ws.WebServiceRef;

@WebServlet(name = "AccountManagement", urlPatterns = {"/accountManagement/*"})
public class AccountManagement extends HttpServlet {

    @WebServiceRef(wsdlLocation = "WEB-INF/wsdl/localhost_8080/WineXpress-war/NotificationManagementWS.wsdl")
    private NotificationManagementWS_Service service_1;

    @WebServiceRef(wsdlLocation = "WEB-INF/wsdl/localhost_8080/WineXpress-war/AccountManagementWS.wsdl")
    private AccountManagementWS_Service service;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, Exception_Exception {
        response.setContentType("text/html;charset=UTF-8");
        RequestDispatcher dispatcher;
        ServletContext servletContext = getServletContext();
        String page = request.getPathInfo();
        page = page.substring(1);
        HttpSession session = request.getSession();

        //Get Number of Items in Cart
        int count = 0;

        if (session.getAttribute("items") == null) {
            int i = 0;
            request.setAttribute("itemsnum", i);
        } else {
            String items = (String) session.getAttribute("items");
            String[] array = items.split("\\;");
            for (int i = 1; i < array.length; i = i + 2) {
                count = count + Integer.parseInt(array[i]);
            }
            request.setAttribute("itemsnum", count);
        }
        //End Number of Items in Cart

        if ("registerResult".equals(page)) {
            request.setAttribute("result", registerCustomer(request));
        } else if ("registerNewAdminResult".equals(page)) {
            request.setAttribute("result", registerAdmin(request));
        } else if ("activateAccountResult".equals(page)) {
            request.setAttribute("result", activateAccount(request));
        } else if ("adminParticularResult".equals(page)) {
            String referer = request.getHeader("referer");
            if (referer != null && referer.contains("adminPaticular.jsp") && request.getParameter("particularForm") != null) {
                Admin admin = updateAdminParticular(request);
                session.setAttribute(SessionAttributes.USER_FIRST_NAME, admin.getFirstName());
                session.setAttribute(SessionAttributes.USER_LAST_NAME, admin.getLastName());
                session.setAttribute(SessionAttributes.USER_EMAIL, admin.getEmail());
                session.setAttribute(SessionAttributes.USER_PHONE_NUMBER, admin.getPhoneNumber());
                session.setAttribute(SessionAttributes.USER_AGE, admin.getAge());
            }
        } else if ("customerParticularResult".equals(page)) {
            String referer = request.getHeader("referer");
            if (referer != null && referer.contains("customerPaticular.jsp") && request.getParameter("particularForm") != null) {
                Customer customer = updateCustomerParticular(request);
                session.setAttribute(SessionAttributes.USER_FIRST_NAME, customer.getFirstName());
                session.setAttribute(SessionAttributes.USER_LAST_NAME, customer.getLastName());
                session.setAttribute(SessionAttributes.USER_EMAIL, customer.getEmail());
                session.setAttribute(SessionAttributes.USER_PHONE_NUMBER, customer.getPhoneNumber());
                session.setAttribute(SessionAttributes.USER_AGE, customer.getAge());
                session.setAttribute(SessionAttributes.CUSTOMER_ADDRESS, customer.getAddress());
                session.setAttribute(SessionAttributes.CUSTOMER_CREDIT_CARD_NUMBER, customer.getCreditCardNumber());
            }
        } else if ("changePasswordResult".equals(page)) {
            if (updatePassword(new Long((String) request.getSession().getAttribute(SessionAttributes.USER_ID)), request.getParameter("password"), request.getParameter("newPassword"))) {
                session.setAttribute(SessionAttributes.PASSWORD_UPDATE_SUCCESS, true);
            } else {
                session.setAttribute(SessionAttributes.PASSWORD_UPDATE_SUCCESS, false);
            }
            session.setAttribute(SessionAttributes.USER_ID, null);
        } else if ("cancelAdminAccountResult".equals(page)) {
            String result = cancelAccount((String) session.getAttribute(SessionAttributes.USER_ID), request.getParameter("password"));
            request.setAttribute("result", result);
            session.setAttribute(SessionAttributes.USER_ID, null);
        } else if ("customerSearchResult".equals(page)) {
            Customer customer = null;
            if (request.getParameter("email") != null) {
                customer = getCustomerByEmail(request.getParameter("email"));
            } else if (StringValidator.isNumeric(request.getParameter("id"))) {
                customer = getCustomerById(new Long(request.getParameter("id")));
            }
            request.setAttribute("customer", customer);
        } else if ("customerSearchResultOrder".equals(page)) {
            Customer customer = null;
            if (request.getParameter("email") != null) {
                customer = getCustomerByEmail(request.getParameter("email"));
            } else if (StringValidator.isNumeric(request.getParameter("id"))) {
                customer = getCustomerById(new Long(request.getParameter("id")));
            }
            request.setAttribute("customer", customer);
        } else if ("deleteCustomerAccountResult".equals(page)) {
            String id = request.getParameter("customerID");
            if (StringValidator.isNumeric(id) && deleteCustomerAccount(new Long(id))) {
                request.setAttribute("result", "Customer account deleted");
            } else {
                request.setAttribute("result", "Fail to delete customer account");
            }
        } else if ("forgetPasswordResult".equals(page)) {
            AccountManagementWS port = service.getAccountManagementWSPort();
            String email = request.getParameter("inputEmail");
            String pwd = port.forgetPassword(email);
            if (pwd != null) {
                request.setAttribute("newpwd", pwd);
                request.setAttribute("email", email);
                User user = new User();
                user.setEmail(email);
                user.setPassword(pwd);
                port.forgetPasswordEmail(user);
            } else {
                response.sendRedirect("/WineXpressClient/forgetPasswordFail.jsp");
                return;
            }
        }
        dispatcher = servletContext.getNamedDispatcher(page);
        if (dispatcher == null) {
            dispatcher = servletContext.getNamedDispatcher("Error");
        }
        dispatcher.forward(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            processRequest(request, response);
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            processRequest(request, response);
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }

    private String registerCustomer(HttpServletRequest request) {
        AccountManagementWS port = service.getAccountManagementWSPort();
        String email = request.getParameter("email");

        String phoneNumber = request.getParameter("phoneNumber");
        String subscribe = request.getParameter("subscribe");

        Customer customer = new Customer();
        customer.setEmail(email);
        customer.setPassword(request.getParameter("password"));
        customer.setFirstName(request.getParameter("firstName"));
        customer.setLastName(request.getParameter("lastName"));
        customer.setCreditCardNumber(request.getParameter("creditCardNumber"));
        customer.setAddress(request.getParameter("address"));
        customer.setPhoneNumber(request.getParameter("phoneNumber"));

        if (subscribe != null) {
            addSubscriber(email);
            customer.setSubscribed(true);
        }
        int age;
        if (StringValidator.isInteger(request.getParameter("age"))) {
            age = Integer.valueOf(request.getParameter("age"));
            customer.setAge(age);
        } else {
            return "Age is not a valid integer";
        }
        try {
            return port.registerCustomer(customer);
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    private String activateAccount(HttpServletRequest request) {
        AccountManagementWS port = service.getAccountManagementWSPort();
        User user = new User();
        String userID = request.getParameter("userID");
        user.setId(Long.valueOf(userID));
        user.setActivationCode(request.getParameter("activationCode"));
        try {
            if (StringValidator.isNumeric(userID) && port.activateAccount(user)) {
                return "User account successfully activated. You may login with your email and password.";
            }
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
        return "Fail to activate account";
    }

    private String cancelAccount(String userID, String password) {
        AccountManagementWS port = service.getAccountManagementWSPort();
        User user = new User();
        user.setId(Long.valueOf(userID));
        user.setPassword(password);
        try {
            if (StringValidator.isNumeric(userID) && port.cancelAccount(user)) {
                return "User account is cancelled.";
            }
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
        return "Fail to cancel account";
    }

    private Admin updateAdminParticular(HttpServletRequest request) throws Exception_Exception {
        Long id = new Long((String) request.getSession().getAttribute(SessionAttributes.USER_ID));
        com.winexpress.account.AccountManagementWS port = service.getAccountManagementWSPort();

        Admin admin = port.getAdmin(id);
        admin.setEmail(request.getParameter("email"));
        admin.setFirstName(request.getParameter("firstName"));
        admin.setLastName(request.getParameter("lastName"));
        admin.setPhoneNumber(request.getParameter("phoneNumber"));
        int age = Integer.valueOf(request.getParameter("age"));
        admin.setAge(age);

        try {
            return port.updateAdminParticular(admin);
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    private Customer updateCustomerParticular(HttpServletRequest request) {
        Long id = new Long((String) request.getSession().getAttribute(SessionAttributes.USER_ID));
        com.winexpress.account.AccountManagementWS port = service.getAccountManagementWSPort();

        Customer customer = port.getCustomerById(id);
        customer.setEmail(request.getParameter("email"));
        customer.setFirstName(request.getParameter("firstName"));
        customer.setLastName(request.getParameter("lastName"));
        customer.setPhoneNumber(request.getParameter("phoneNumber"));
        int age = Integer.valueOf(request.getParameter("age"));;
        customer.setAge(age);
        customer.setAddress(request.getParameter("address"));
        customer.setCreditCardNumber(request.getParameter("creditCardNumber"));

        try {
            return port.updateCustomerParticular(customer);
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    private Boolean updatePassword(java.lang.Long id, java.lang.String oldPassword, java.lang.String newPassword) {
        try {
            com.winexpress.account.AccountManagementWS port = service.getAccountManagementWSPort();
            User user = new User();
            user.setId(id);
            user.setPassword(oldPassword);
            user.setEmail(newPassword);
            return port.updatePassword(user);
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

    private Customer getCustomerByEmail(java.lang.String email) {
        com.winexpress.account.AccountManagementWS port = service.getAccountManagementWSPort();
        Customer customer = null;
        try {
            customer = port.getCustomerByEmail(email);
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
        return customer;
    }

    private Customer getCustomerById(java.lang.Long id) {
        com.winexpress.account.AccountManagementWS port = service.getAccountManagementWSPort();
        return port.getCustomerById(id);
    }

    private Boolean deleteCustomerAccount(java.lang.Long id) {
        com.winexpress.account.AccountManagementWS port = service.getAccountManagementWSPort();
        try {
            return port.deleteCustomerAccount(id);
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

    private String registerAdmin(HttpServletRequest request) {
        com.winexpress.account.AccountManagementWS port = service.getAccountManagementWSPort();
        Admin admin = new Admin();
        String email = request.getParameter("email");
        admin.setEmail(email);
        admin.setFirstName(request.getParameter("firstName"));
        admin.setLastName(request.getParameter("lastName"));
        admin.setPhoneNumber(request.getParameter("phoneNumber"));

        int age;
        if (StringValidator.isInteger(request.getParameter("age"))) {
            age = Integer.valueOf(request.getParameter("age"));
            admin.setAge(age);
        } else {
            return "Age is not a valid integer";
        }
        try {
            return port.registerAdmin(admin);
        } catch (Exception_Exception ex) {
            Logger.getLogger(AccountManagement.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    private boolean addSubscriber(java.lang.String email) {
        com.winexpress.support.NotificationManagementWS port = service_1.getNotificationManagementWSPort();
        return port.addSubscriber(email);
    }

}
